package com.application.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.application.common.utils.wx.WxUtils;
import com.application.model.UserPoint;
import com.application.service.UserService;
import com.application.vo.UserVo;
import com.jfinal.aop.Clear;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.platform.annotation.Controller;
import com.platform.interceptor.AuthInterceptor;
import com.platform.interceptor.LoginInterceptor;
import com.platform.interceptor.ParamPkgInterceptor;
import com.platform.mvc.base.BaseController;
import com.platform.mvc.operator.Operator;
import com.platform.mvc.user.User;
import com.platform.tools.ToolHttp;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 公开获取
 */
@Controller("/api/public")
@Clear({LoginInterceptor.class, AuthInterceptor.class, ParamPkgInterceptor.class})
public class PublicApiController extends BaseController {

    /**
     * 请求腾讯获取微信openid
     * https://api.weixin.qq.com/sns/jscode2session?appid=wx1776d46100cf72b3&secret=96d5e38f1dc8aa35604413f241ca8c6b&js_code=001e142H03eobg223C0H0Lzc2H0e142T&grant_type=authorization_code
     * <p>
     * 返回示例：{"session_key":"\/1Gk09dUtnIdHH4gYsRR1g==","openid":"oscrs4s5H6DlGh8abudqC_Iu4LRk"}
     */
    public void openid() {
        String code = getPara("code");
        if (StrKit.isBlank(code)) {
            error(400, "code错误");
            return;
        }
        Map<String, String> map = getUserInfo(code);
        if (map.get("openid") != null) {
            success(map);
            return;
        }
        error(500, "获取用户信息失败");
    }

    private Map<String, String> getUserInfo(String code) {
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?" +
                "appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code";

        requestUrl = requestUrl.replace("{appid}", PropKit.get("xcx.appid"))
                .replace("{secret}", PropKit.get("xcx.secret"))
                .replace("{code}", code);
        String result = ToolHttp.get(true, requestUrl);
        if (result != null) {
            System.out.println(result);
            Map<String, String> map = (Map<String, String>) JSON.parse(result);
            return map;
        }
        return new HashMap<>();
    }


    public void loginWx() {
        String encryptedData = getPara("encryptedData");
        String code = getPara("code");
        String iv = getPara("iv");
        String key = getPara("session_key");
        Map<String, Object> map = new HashMap<>();
        if(StrKit.notBlank(key)) {
            map = authLogin(encryptedData, key, iv, "");
        } else {
            try {
                Map<String, String> userInfo = getUserInfo(code);
                key = userInfo.get("session_key");
                String openid = userInfo.get("openid");
                map = authLogin(encryptedData, key, iv, openid);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if((int)map.get("code") == 0) {
            success(map.get("data"));
        } else {
            error(500, String.valueOf(map.get("msg")));
        }
    }

    /**
     * 微信小程序手机号登陆
     *
     * @param encryptedData
     * @param session_key
     * @param iv
     * @return
     */
    private Map<String, Object> authLogin(String encryptedData, String session_key, String iv, String openid) {
        Map<String, Object> map = new HashMap<>();

        String result = WxUtils.wxDecrypt(encryptedData, session_key, iv);
        JSONObject json = JSONObject.parseObject(result);
        printLog(encryptedData, session_key, iv, json);
        if (json.containsKey("phoneNumber")) {
            String phone = json.getString("phoneNumber");
            if (StringUtils.isNoneBlank(phone)) {
                map.put("code", 0);
                map.put("msg", "成功");
                map.put("data", loginNext(phone, openid, null));
            } else {
                map.put("code", 4001);
                map.put("msg", "失败！用户未绑定手机号");
                map.put("data", "");
            }
        } else {
            map.put("code", 4001);
            map.put("msg", "获取失败！");
            map.put("data", "");
        }

        return map;
    }

    private void printLog(String encryptedData, String session_key, String iv, JSONObject json) {
        System.out.println("#####微信登陆请求参数##########");
        System.out.println("session_key: " + session_key);
        System.out.println("encryptedData: " + encryptedData);
        System.out.println("iv: " + iv);
        System.out.println("微信登陆解密信息；");
        System.out.println(json);
    }

    private UserVo loginNext(String username, String openid, String img) {
        User user = User.dao.findByUsername(username);
        if (user == null) {
            user = new UserService().registerUser(username, openid, "wx", username, img);
        }
        return getLoginResult(user);
    }

    private UserVo getLoginResult(User user) {
        AuthInterceptor.setCurrentUser(getRequest(), getResponse(), user, false);
        User.updateInfo(user);
        //pay_pass支付密码加密处理
        String payPassStr = user.getStr("pay_pass");
        String pay_pass = payPassStr == null ? null : DigestUtils.md5Hex(payPassStr).toUpperCase();
        user.set("pay_pass", pay_pass);
        Operator operator = Operator.cacheGet("/api/stats/product");
        int stats = (operator != null && AuthInterceptor.hasPrivilegeUrl(operator.getIds(), user.getId().toString()))
                ? 1 : 0;
        //返回用户是否已签到
        UserPoint point = UserPoint.dao.loginCheck(user.getId());
        //处理用户余额money=money+gift
        user.set("money", user.getBigDecimal("money").add(user.getBigDecimal("gift")));
        return new UserVo(getAttr("authmark"), user, stats, point == null ? 0 : 1);
    }

}
